Refresh Token হল একটি নিরাপদ উপায় যা ব্যবহারকারীদের তাদের অ্যাপ্লিকেশন সেশনকে পুনরায় বৈধ করতে সহায়তা করে যখন তাদের Access Token মেয়াদ শেষ হয়ে যায়। সাধারণত, Access Token এর মেয়াদ সীমিত (যেমন 1 ঘণ্টা) এবং একবার এটি শেষ হয়ে গেলে, ব্যবহারকারীদের নতুন Token পেতে Refresh Token প্রয়োজন। Refresh Token সাধারণত দীর্ঘ মেয়াদী এবং নিরাপদে সংরক্ষিত হয়।
Spring Security এর সাথে Refresh Token বাস্তবায়ন করতে আমরা নিম্নলিখিত পদক্ষেপ অনুসরণ করতে পারি:
- Access Token এবং Refresh Token তৈরি করা
- Refresh Token যাচাই এবং নতুন Access Token তৈরি করা
- Spring Security Configuration এর মাধ্যমে Filter এবং Endpoint তৈরি করা
1. Access Token এবং Refresh Token তৈরি করা
প্রথমে, আমরা JWT ব্যবহার করে Access Token এবং Refresh Token তৈরি করব। Access Token মেয়াদ সীমিত এবং Refresh Token দীর্ঘ মেয়াদী থাকে।
JWT Token Utility:
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
public class JwtUtil {
private static final String SECRET_KEY = "mySecretKey";
private static final long ACCESS_TOKEN_EXPIRATION = 3600000; // 1 hour
private static final long REFRESH_TOKEN_EXPIRATION = 86400000; // 24 hours
// Access Token তৈরি
public static String generateAccessToken(String username) {
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + ACCESS_TOKEN_EXPIRATION))
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
// Refresh Token তৈরি
public static String generateRefreshToken(String username) {
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + REFRESH_TOKEN_EXPIRATION))
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
}
2. Refresh Token যাচাই এবং নতুন Access Token তৈরি করা
ব্যবহারকারী যখন তাদের Access Token এর মেয়াদ শেষ হয়ে যায়, তখন তারা Refresh Token পাঠায় এবং নতুন Access Token পেতে পারে।
Refresh Token Endpoint:
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/auth")
public class AuthenticationController {
// Refresh Token দিয়ে নতুন Access Token তৈরি করা
@PostMapping("/refresh")
public ResponseEntity<?> refreshToken(@RequestBody TokenRefreshRequest request) {
String refreshToken = request.getRefreshToken();
// Refresh Token যাচাই করুন
if (JwtUtil.validateToken(refreshToken)) {
String username = JwtUtil.getUsernameFromToken(refreshToken);
String newAccessToken = JwtUtil.generateAccessToken(username);
return ResponseEntity.ok(new JwtResponse(newAccessToken));
} else {
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("Invalid refresh token");
}
}
}
TokenRefreshRequest:
public class TokenRefreshRequest {
private String refreshToken;
// Getter এবং Setter
public String getRefreshToken() {
return refreshToken;
}
public void setRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}
}
JwtResponse:
public class JwtResponse {
private String accessToken;
// Constructor, Getter এবং Setter
public JwtResponse(String accessToken) {
this.accessToken = accessToken;
}
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
}
3. Spring Security Configuration এবং Filter:
Spring Security Configuration এর মধ্যে আমরা JWT Authentication Filter এবং JWT Refresh Token Filter তৈরি করতে পারি।
JWT Authentication Filter:
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import io.jsonwebtoken.Claims;
public class JwtAuthenticationFilter extends OncePerRequestFilter {
private static final String SECRET_KEY = "mySecretKey";
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String token = request.getHeader("Authorization");
if (token != null && token.startsWith("Bearer ")) {
token = token.substring(7); // "Bearer " বাদ দিন
if (JwtUtil.validateToken(token)) {
Claims claims = JwtUtil.validateToken(token);
String username = claims.getSubject();
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(username, null, new ArrayList<>());
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
filterChain.doFilter(request, response);
}
}
JWT Token Validation Utility:
public class JwtUtil {
private static final String SECRET_KEY = "mySecretKey";
public static Claims validateToken(String token) {
return Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody();
}
public static String getUsernameFromToken(String token) {
return validateToken(token).getSubject();
}
}
4. Spring Security Configuration:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/auth/refresh").permitAll()
.anyRequest().authenticated()
.and()
.addFilter(new JwtAuthenticationFilter());
}
}
প্রকল্পের Flow:
- ব্যবহারকারী প্রথমবার লগইন করলে, একটি Access Token এবং একটি Refresh Token জেনারেট করা হবে এবং তাদের ক্লায়েন্টে পাঠানো হবে।
- Access Token এর মেয়াদ শেষ হলে, ব্যবহারকারী তাদের Refresh Token পাঠিয়ে নতুন Access Token পেতে পারবে।
- Refresh Token মেয়াদ শেষ হলে, ব্যবহারকারী আবার লগইন করতে হবে।
Spring Security Refresh Token এর সুবিধা:
- সতর্কভাবে Access Token এর মেয়াদ সীমিত করা:
- Access Token এর মেয়াদ কম রাখলে, এটি কম সময়ের জন্য বৈধ থাকে এবং সুরক্ষিত থাকে।
- ব্যবহারকারী অভিজ্ঞতা উন্নত করা:
- ব্যবহারকারীদের পুনরায় লগইন না করেই নতুন Access Token পাওয়া যায়।
- Refresh Token এর সুরক্ষা:
- Refresh Token সাধারণত দীর্ঘমেয়াদী হয় এবং এটি সুরক্ষিতভাবে সংরক্ষণ করা উচিত।
- Scalability এবং Stateless Authentication:
- Refresh Token এর মাধ্যমে নিরাপদ Stateless Authentication নিশ্চিত করা যায়।
এভাবে Spring Security এ Refresh Token ইমপ্লিমেন্ট করা যায়, যা Access Token মেয়াদ শেষ হলে ব্যবহারকারীদের সহজেই সেশন পুনঃপ্রবিষ্ট করতে সহায়ক।
Read more